<template>
    <div class="chat-body">
        <div class="chat-header">
            <div class="flex-center-center">
                <span class="fz20">
                    Total: {{ chatTotal }}
                </span>
            </div>
        </div>
        <div
            id="chat-box"
            ref="chatRef"
            class="chat-box"
        >
            <div ref="chatBoxRef">
                <div
                    v-for="(item, index) in chatList"
                    :key="`chat-item-${index}`"
                    class="flex-start-start chat-item"
                    :class="{'mine': item.mine, 'warn': item.type === 'warn'}"
                >
                    <template v-if="item.type === 'warn'">
                        <div>
                            {{ item.message }}
                        </div>
                    </template>
                    <template v-else>
                        <div class="chat-item-avatar">
                            <img
                                :src="item.userImage || headImg"
                                @error="setImage"
                            >
                        </div>
                        <div class="chat-item-content">
                            <div class="chat-item-name">
                                <span>{{ item.userName }}</span>
                            </div>
                            <div class="chat-item-msg">
                                <span v-html="item.message" />
                            </div>
                            <div
                                v-if="item.timeStr"
                                class="fz10 chat-item-time"
                            >
                                {{ moment(item.time).fromNow() }}
                            </div>
                        </div>
                    </template>
                </div>
            </div>
        </div>
        <div class="chat-input flex-start-center">
            <el-input
                v-model="chatInput"
                placeholder="Please input message"
                size="large"
                class="flex-1"
                @keyup.enter="send"
            />
            <el-button
                type="primary"
                @click="send"
            >
                Send
            </el-button>
        </div>
        <div
            v-if="!chatAutoScroll"
            class="flex-center-center chat-end"
            @click="chatAutoScroll = true; chatScroll();"
        >
            <el-icon size="34">
                <CaretBottom />
            </el-icon>
        </div>
    </div>
</template>

<script setup>
import { CaretBottom } from '@element-plus/icons-vue';
import moment from 'moment';
import types from '@/store/types';
import { debounce } from '@/utils/tools';
import { getMessageList } from '@/utils/api';

const {
    dispatch, state,
} = useStore();
const router = useRouter();
const chatWs = computed(() => state.ws.chatWs);
const chatInput = ref('');
const chatList = computed(() => state.ws.chatList);
const chatTotal = computed(() => state.ws.chatTotal);
const chatRef = ref('');
const chatBoxRef = ref('');
const chatAutoScroll = ref(true);

const getHistoryMessage = async (height) => {
    const time = chatList.value?.[0]?.time;
    const res = await getMessageList({ time });
    const { code, data } = res;

    if (code === 200 && data) {
        chatList.value.unshift(...data);

        nextTick(() => {
            chatRef.value.scrollTop = chatBoxRef.value.clientHeight - height;
        });
    }
};

const chatScroll = () => {
    if (chatAutoScroll.value) {
        chatRef.value.scrollTop = chatRef.value.scrollHeight;
    }
};

const handleMsg = (res) => {
    const { data, type } = res;

    if (type === 'msg' || type === 'warn') {
        if (data.time && new Date().getTime() - data.time > 30 * 1000 * 60) {
            data.timeStr = moment(data.time).fromNow();
        }

        chatList.value.push({
            ...data,
            message: data.message.replace(/\\n/, '<br>'),
            type,
        });

        nextTick(() => {
            chatScroll();
        });
    } else if (type === 'login') {
        chatTotal.value = data.total;
    }
};

const handleScroll = debounce(async () => {
    const top = chatRef.value.scrollTop;
    const height = chatRef.value.clientHeight;
    chatAutoScroll.value = top + height === chatRef.value.scrollHeight;

    if (top < 60) {
        await getHistoryMessage(chatBoxRef.value.clientHeight);
    }
}, 100);

const send = () => {
    if (chatWs.value && chatInput.value) {
        chatWs.value.sub({
            type: 'msg',
            data: chatInput.value,
        }, handleMsg);
        chatInput.value = '';
        chatAutoScroll.value = true;
        chatScroll();
    }
};

onMounted(() => {
    dispatch(types.INIT_CHAT_WS, chatScroll);
    chatScroll();
    chatRef.value.addEventListener('scroll', handleScroll);

    const { WebApp } = window?.Telegram || {};

    if (WebApp) {
        WebApp.BackButton.show();
        WebApp.BackButton.onClick(() => {
            router.push('/');
        });
    }
});
</script>

<style lang="scss" scoped>
.chart-box {
    border-radius: 6px;
    padding: 10px;

    @extend %border-primary;
}

.chat-body {
    box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.1);
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    font-size: 14px;
    transition: 0.5s;
    background-color: #fff;
    flex: 1;
    height: 100%;

    .chat-header {
        position: relative;
        padding: 0 20px;
        border-top-left-radius: 6px;
        border-top-right-radius: 6px;

        & > div {
            height: 60px;
        }

        .chat-header-close {
            position: absolute;
            right: 20px;
        }
    }

    .chat-box {
        flex: 1;
        overflow-y: auto;
        padding: 10px;
        background-color: #f8f9fa;

        & > div {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
    }

    .chat-item {
        gap: 10px;
        padding-right: 60px;

        .chat-item-name {
            color: #666;
            font-size: 12px;
        }

        .chat-item-avatar {
            display: flex;

            img {
                width: 46px;
            }
        }

        .chat-item-content {
            display: flex;
            flex-direction: column;
            gap: 5px;
        }

        .chat-item-msg {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            gap: 5px;

            span {
                display: flex;
                padding: 10px;
                background-color: #fff;
                border-radius: 10px;
                box-shadow: 0 0 5px #eee;
                line-height: 1.6;
                color: #333;
            }
        }

        .chat-item-time {
            color: #999;
        }

        &.mine {
            justify-content: end;
            flex-direction: row-reverse;
            padding-right: 0;
            padding-left: 60px;

            .chat-item-name {
                text-align: right;
            }

            .chat-item-msg {
                align-items: flex-end;

                span {
                    background-color: #8ae95e;
                }
            }

            .chat-item-time {
                text-align: right;
            }
        }

        &.warn {
            justify-content: center;

            & > div {
                width: 60%;
                text-align: center;
                padding: 10px 0;
                font-size: 12px;

                @extend %text-error;
            }
        }
    }

    .chat-input {
        --el-component-size-large: 50px;

        padding-right: 10px;
        border-top: 1px solid #eee;

        :deep() {
            .el-input__wrapper {
                box-shadow: none;
                padding: 10px;
                border-radius: 0;
            }

            .el-input__inner {
                border-radius: 20px;
                background-color: #f1f1f1;
                padding-left: 20px;
                padding-right: 20px;
                height: 40px;
            }

            .el-input-group__append {
                box-shadow: none;
                background-color: transparent;
            }
        }
    }

    .chat-end {
        position: absolute;
        bottom: 120px;
        right: 10px;
        height: 40px;
        width: 40px;
        background-color: #fff;
        opacity: 0.5;
        cursor: pointer;
    }
}
</style>
